package com.macro.mall.tiny.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import io.swagger.v3.core.converter.AnnotatedType;
import io.swagger.v3.core.converter.ModelConverters;
import io.swagger.v3.core.converter.ResolvedSchema;
import io.swagger.v3.core.util.Json;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.media.DateTimeSchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.StringSchema;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springdoc.core.customizers.OpenApiCustomizer;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * SpringDoc API文档相关配置
 * Created by macro on 2022/3/4.
 */
@Configuration
public class SpringDocConfig {
    private static final String SECURITY_SCHEME_NAME = "Authorization";
    
    @Bean
    public OpenAPI mallTinyOpenAPI() {
        // 配置Jackson ObjectMapper以处理LocalDateTime格式
        ObjectMapper objectMapper = Json.mapper();
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        objectMapper.registerModule(javaTimeModule);
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        
        return new OpenAPI()
                .info(new Info()
                        .title("mall-tiny项目骨架")
                        .description("mall-tiny项目骨架相关接口文档")
                        .version("v1.0.0")
                        .license(new License()
                                .name("Apache 2.0")
                                .url("https://xxx.com")))
                .externalDocs(new ExternalDocumentation()
                        .description("SpringBootmall")
                        .url("https://xxxx.com"))
                .addSecurityItem(new SecurityRequirement().addList(SECURITY_SCHEME_NAME))
                .components(new Components()
                        .addSecuritySchemes(SECURITY_SCHEME_NAME,
                                new SecurityScheme()
                                        .name(SECURITY_SCHEME_NAME)
                                        .type(SecurityScheme.Type.HTTP)
                                        .scheme("bearer")
                                        .bearerFormat("JWT")));
    }

    @Bean
    public OpenApiCustomizer openApiCustomizer() {
        return openApi -> {
            // 为所有DateTimeSchema设置示例格式
            openApi.getComponents().getSchemas().values().forEach(this::updateSchemaProperties);
            
            // 为LocalDateTime类型设置全局格式
            Map<String, Schema> schemas = openApi.getComponents().getSchemas();
            if (schemas == null) {
                schemas = new HashMap<>();
                openApi.getComponents().setSchemas(schemas);
            }
            
            // 为LocalDateTime创建自定义Schema
            Schema localDateTimeSchema = new StringSchema();
            localDateTimeSchema.setType("string");
            localDateTimeSchema.setFormat("date-time");
            localDateTimeSchema.setExample("2025-11-21 01:52:34");
            localDateTimeSchema.setDescription("时间格式: yyyy-MM-dd HH:mm:ss");
            schemas.put("LocalDateTime", localDateTimeSchema);
        };
    }
    
    /**
     * 递归更新Schema中的时间属性
     */
    private void updateSchemaProperties(Schema schema) {
        if (schema == null) return;
        
        // 更新当前Schema的属性
        Map<String, Schema> properties = schema.getProperties();
        if (properties != null) {
            properties.replaceAll((propertyName, propertySchema) -> {
                if (propertySchema instanceof DateTimeSchema) {
                    StringSchema stringSchema = new StringSchema();
                    stringSchema.setType("string");
                    stringSchema.setFormat("date-time");
                    stringSchema.setExample("2025-11-21 01:52:34");
                    stringSchema.setDescription("时间格式: yyyy-MM-dd HH:mm:ss");
                    return stringSchema;
                }
                // 递归处理嵌套对象
                updateSchemaProperties(propertySchema);
                return propertySchema;
            });
        }
        
        // 处理items中的Schema（如数组元素）
        if (schema.getItems() != null) {
            updateSchemaProperties(schema.getItems());
        }
    }

    /* 2. ums 模块分组 */
    @Bean
    public GroupedOpenApi umsGroup() {
        return GroupedOpenApi.builder()
                .group("ums")                                         // 下拉框显示名称
                .packagesToScan("com.macro.mall.tiny.modules.ums.controller")
                .build();
    }

    /* 3. pms 模块分组 */
    @Bean
    public GroupedOpenApi pmsGroup() {
        return GroupedOpenApi.builder()
                .group("pms")
                .packagesToScan("com.macro.mall.tiny.modules.pms.controller")
                .build();
    }

    /* 3. oms 模块分组 */
    @Bean
    public GroupedOpenApi omsGroup() {
        return GroupedOpenApi.builder()
                .group("oms")
                .packagesToScan("com.macro.mall.tiny.modules.oms.controller")
                .build();
    }

    /* 4. bms 模块分组 */
    @Bean
    public GroupedOpenApi bmsGroup() {
        return GroupedOpenApi.builder()
                .group("bms")
                .packagesToScan("com.macro.mall.tiny.modules.bms.controller")
                .build();
    }
}